On-demand Revalidation
https://nextjs.org/docs/app/building-your-application/caching#on-demand-revalidation
https://scrapbox.io/files/66e7c77e676efd001c842d98.png
有効期限内(invalidate するまで)はキャッシュを返す
「任意のタイミング」でキャッシュを無効化する
On-demand Revalidation を実行するために、 2 つの API が用意されている
revalidatePath: https://nextjs.org/docs/app/building-your-application/caching#revalidatepath
特定の Route のパスでキャッシュを無効化する
code:ts
revalidatePath(/photos/${photoId});
revalidateTag: https://nextjs.org/docs/app/building-your-application/caching#fetch-optionsnexttags-and-revalidatetag
特定のタグ文字列でキャッシュを無効化する
code:ts
revalidateTag(photos?authorId=${session.user.id});
上記のタグでキャッシュが生成されるデータ取得関数は以下の getPhotos である
code:ts
export function getPhotos({
...
}: Props): Promise<{ photos: Photo[]; pagination: PaginationProps }> {
// ...
return fetch(path(/api/photos?${searchParams}), {
next: {
// ここでタグを指定する
...(authorId && { tags: [photos?authorId=${authorId}] }),
...(revalidate !== undefined && { revalidate }),
},
})
.then(handleSucceed)
.catch(handleFailed);
}
Route に依存しないため、revalidatePath よりも効率よくキャッシュの無効化が行える
warning.icon 実行しても、対象のキャッシュが即座に再作成されるわけではない
キャッシュが再作成されるのは、必要になったタイミング(リクエスト時)
https://arc.net/l/quote/azqvyvlg
When an on-demand revalidation is triggered, the appropriate cache entries will be purged from the cache.
This is different from time-based revalidation, which keeps the stale data in the cache until the fresh data is fetched.
Time-base Revalidation とは異なり、無効化されたキャッシュを返さない
Route Handler で用いる際の注意
revalidateTag は Route Handler でも実行できるが注意が必要
Router Handler の On-demand Revalidation で変更を即座に確認したい場合、router.refresh との併用が必須
https://arc.net/l/quote/uudllmdf
Revalidating the Data Cache in a Route Handler will not immediately invalidate the Router Cache as the Route Handler isn't tied to a specific route.
This means Router Cache will continue to serve the previous payload until a hard refresh, or the automatic invalidation period has elapsed.
Client-side Router Cache のキャッシュにヒットするため
router.refresh を実行すると Router Cache を削除できる
しかし、現在の Router のレンダリングを再リクエストするため、場合によっては(e.g. router.push で別画面に遷移するなど)このリクエストが余計なものになる
以上を考慮すると、Server Actions を優先して使った方が良い
しかし、Next.js のアプリケーションの外側から On-demand Revalidation を呼び出す場合は Router Handler に頼らざるを得ない
e.g. ブログ記事
外部の CMS でブログ記事を書き、Next.js でその CMS からデータを取得する構成
記事データが更新されたタイミングで、Webhook を経由して On-demand Revalidation を実行すると、効率よくキャッシュを無効化できる
Server Actions による On-demand Revalidation のメリット
router.refresh を実行せずとも Router Cache が削除される
https://arc.net/l/quote/xyzvkagt
This will invalidate the Router Cache for the associated route.
redirect で遷移させると、更新と同時に画面遷移させることが可能
https://nextjs.org/docs/app/building-your-application/routing/redirecting#redirect-function
Server Component、Route Handler、Server Actions でのみ利用可能な関数
キャッシュタグの設計
revalidateTag はデータ取得時に与えた「任意のタグ文字列」によって、タグ付けされたキャッシュを無効化する
code:ts
fetch(https://..., { next: { tags: 'a', 'b', 'c' } })
revalidateTag('a')
この「任意のタグ文字列」をどのような文字列にするかがポイント
キャッシュ戦略
このとき考慮すべきは以下の 2 点
タグが具体的であればあるほど、データソースアクセス効率が良好になる
e.g. 「このページの何番目」のように具体的なタグ文字列
タグが抽象的であればあるほど、無効化は楽になる
e.g. 何番目という指定はせず、このページを指す文字列